#include <gtest/gtest.h>
#include "structural_simulation_class.h"

TEST(BernoulliBeam20x, Pressure)
{
	Real scale_stl = 0.001;
	Real end_time = 0.15;

	Real rho_0 = 6.45e3; // Nitinol
	Real poisson = 0.3;
	Real Youngs_modulus = 5e8;
	Real physical_viscosity = Youngs_modulus / 100;
	Real pressure = 1e3;

	/** STL IMPORT PARAMETERS */
	std::string relative_input_path = "./input/"; //path definition for linux
	std::vector<std::string> imported_stl_list = { "bernoulli_beam_20x.stl" };
	std::vector<Vec3d> translation_list = { Vec3d(0) };
	std::vector<Real> resolution_list = { 10.0 / 6.0 };
	LinearElasticSolid material = LinearElasticSolid(rho_0, Youngs_modulus, poisson);
	std::vector<LinearElasticSolid> material_model_list = { material };

	TriangleMeshShape specimen("./input/bernoulli_beam_20x.stl", Vec3d(0), scale_stl);
	BoundingBox fixation = specimen.findBounds();
	fixation.second[0] = fixation.first[0] + 0.01;
	
	StructuralSimulationInput input
	{
		relative_input_path,
		imported_stl_list,
		scale_stl,
		translation_list,
		resolution_list,
		material_model_list,
		{physical_viscosity},
		{}
	};
	input.surface_particles_only_to_vtu_ = { true };
	input.body_indeces_fixed_constraint_region_ = StdVec<ConstrainedRegionPair>{ ConstrainedRegionPair(0, fixation) };
	StdVec<array<Real, 2>> pressure_over_time = {
		{0.0, 0.0},
		{end_time * 0.1, pressure},
		{end_time, pressure }
	};
	input.surface_pressure_tuple_ = StdVec<PressureTuple>{ PressureTuple(0, &specimen, Vec3d(0.1, 0.0, 0.1), pressure_over_time) };
	input.particle_relaxation_list_ = { true };

	//=================================================================================================//
	StructuralSimulation sim(input);
	sim.runSimulation(end_time);

	Real displ_max = sim.getMaxDisplacement(0);
	Real displ_max_analytical = 4.8e-3; // in mm, absolute max displacement
	EXPECT_NEAR(displ_max, displ_max_analytical, displ_max_analytical * 0.1);
	std::cout << "displ_max: " << displ_max << std::endl;
}

int main(int argc, char* argv[])
{	
	testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}
